using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using Sedna.Core.Controller;
using Sedna.Core.Controller.Configurations;
using Sedna.Core.Controls.Support;
using Sedna.Core.Controls.Support.Javascript;
using Sedna.Core.DataBinding;
using Sedna.Core.Tiles.Contents;
using DataBinder = Sedna.Core.DataBinding.DataBinder;

namespace Sedna.Core.Controls
{
	public class ImageButton : System.Web.UI.WebControls.ImageButton, IContent, IControlDataLoadAware, IConfigurationAware, ICommandAware, IClientScriptingControl
	{

		private IImageCommandConfiguration configuration;
		private string configurationId = "configuration.default.ImageButton";
		private string relativePath;
		
		protected Object executionParameter = null;

		private String contentPlaceHolderId;

		protected IDataBinder binder;


        private string clientVariable;
        private bool clientScriptingEnabled;
        private string javascriptClass;

        #region Properties

        public String ContentPlaceHolderId
		{
			get { return contentPlaceHolderId;}
			set { contentPlaceHolderId = value;}
		}

        IConfiguration IConfigurationAware.Configuration
		{
			get { return configuration; }
			set { configuration = (IImageCommandConfiguration)value; }
		}

	    public IImageCommandConfiguration Configuration
	    {
            get { return configuration; }
            set { configuration = value; }
        }
	    
		[Bindable(true), Category("Sedna"), DefaultValue("configuration.default.ImageButton")]
		public string ConfigurationId
		{
			get { return configurationId; }
			set { this.configurationId = value; }
		}
/*
		public string TextKey
		{
			get { return textKey; }
			set { textKey = value; }
		}
*/
		public Object ExecutionParameter
		{
			get{return executionParameter;}
			set{this.executionParameter = value;}
		}

		public string RelativePath
		{
			get { return relativePath; }
			set { relativePath = value; }
		}

		string ICommandAware.OnClick
		{
			get { return Attributes["onclick"]; }
			set { Attributes["onclick"]=value; }
        }

        #endregion


        #region Javascript support
	    
        public bool ClientScriptingEnabled
        {
            get { return clientScriptingEnabled /*|| clientVariable != null*/; }
            set { clientScriptingEnabled = value; }
        }

        public string ClientVariable
        {
            get { return /*clientVariable*/ ControlUtil.GetClientVariable(this, clientVariable); }
            set { clientVariable = value; }
        }

        public string JavascriptClass
        {
            get { return javascriptClass; }
            set { javascriptClass = value; }
        }

        public string NodeName
        {
            get { return ClientID; }
        }


        private void DeclareScriptVariable()
        {
            ControlUtil.EnsureIdAttribute(this);
            JavascriptController.Current.DeclareClass(JavascriptClass);
            if (ClientVariable != null)
            {
                JavascriptController.Current.DeclareObjectByNode(ClientVariable, JavascriptClass, NodeName);
            }
        }

        protected virtual IDictionary BuildScriptParameters()
        {
            IDictionary parameters = new ListDictionary();
            parameters.Add("jsClass", JavascriptClass);
            parameters.Add("id", ClientID);
            parameters.Add("submitState", Text);
            return parameters;
        }	    
        #endregion

        #region Constructors
        public ImageButton() :base()
		{
			//this.CssClass = "btn";
		}

		public ImageButton(IConfiguration configuration) : this()
		{
			Configuration = (IImageCommandConfiguration) configuration;
			ConfigurationId = configuration.ObjectName;
        }

        #endregion

        protected override void OnInit(EventArgs e)
		{
			if(configuration == null)
			{
				configuration = (IImageCommandConfiguration)SpringContextFactory.GetContext().GetObject(configurationId);
			}
			Click += new ImageClickEventHandler(this.OnClick);
			Build();

			ControlUtil.SetupClientAttributes(this, configuration);
			binder=new DataBinder(this, configuration, ExecutionContext.GetCurrent(ClientID));
			base.OnInit (e);
		}

		protected void Build()
		{
			BorderStyle = BorderStyle.None;
            Visible = Configuration.Visible && Configuration.IsVisibleForPrincipal();
            Enabled = Configuration.Enabled && Configuration.IsEnabledForPrincipal();

            ID = Configuration.Id;
            JavascriptClass = Configuration.JavascriptClass;
            CausesValidation = Configuration.CausesValidation;
            ValidationGroup = Configuration.ValidationGroup;
            RelativePath = Configuration.ImageUrl;
		}

		protected void OnClick(object sender, ImageClickEventArgs e)
		{
            if (CausesValidation && !Page.IsValid)
            {
                return;
            }
            System.Web.UI.WebControls.ImageButton button = (System.Web.UI.WebControls.ImageButton)sender;
//			IActionExecutor actionExecutor = (IActionExecutor)SpringContextFactory.GetContext().GetObject("runtime.ActionExecutor");
			IExecutionContext executionContext = ExecutionContext.GetCurrent(ClientID);
			executionContext["infrastructure.commandName"] = button.CommandName;
			executionContext["infrastructure.commandArgument"] = button.CommandArgument;
			ControlUtil.ExecuteAction(executionContext, Context, Configuration, this.ClientID);
//			actionExecutor.ExecuteAction(Context, executionContext, configuration);
			RaiseBubbleEvent(this, new ModelUpdateEventArgs(executionContext));
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			IDictionary executionContext=ExecutionContext.GetCurrent(ClientID);
			Unbind();
			ControlUtil.ExecuteOnLoad(executionContext, Context, Configuration, this.ClientID);

            if (Configuration.VisibleBindPath != null)
                this.Visible = true; // To reach the OnPreRender method and analyze visibility in the Bind method
		}

		public void OnDataLoad()
		{
			IDictionary executionContext=ExecutionContext.GetCurrent(ClientID);
			ControlUtil.ExecuteOnDataLoad(executionContext, Context, Configuration, this.ClientID);
		}

	    protected override void AddAttributesToRender(HtmlTextWriter writer)
	    {
	        base.AddAttributesToRender(writer);
	        ControlUtil.RenderScriptAttributes(writer, BuildScriptParameters());
	    }

	    protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender(e);
			IDictionary executionContext=ExecutionContext.GetCurrent(ClientID);
			ControlUtil.ExecuteOnPreRender(executionContext, Context, Configuration, this.ClientID);
			Bind();

			if(!this.Enabled && configuration.DisabledImageUrl != null)
			{
				this.ImageUrl = configuration.ImageManager.RelateImageUrl(configuration.DisabledImageUrl);
			}
			else
			{
				this.ImageUrl = configuration.ImageManager.RelateImageUrl(RelativePath);
			}

		    if (ClientScriptingEnabled)
		    {
		        DeclareScriptVariable();
		    }
		    
        }

        private void Bind()
		{
            this.Visible = Configuration.Visible;

            binder.Bind(new string[] { "RelativePath", "ImageUrl", "AlternateText", "Enabled", "Visible" });

            Enabled = Enabled && configuration.IsEnabledForPrincipal();
            Visible = Visible && configuration.IsVisibleForPrincipal();

            if (configuration.CommandArgumentGenerator!=null)
            {
                this.CommandName = configuration.CommandName;
                this.CommandArgument = configuration.CommandArgumentGenerator.GenerateCommandArguments(configuration, ExecutionContext.GetCurrent(ClientID));

                AssignJScriptCommand();
            }
		    
		}

		private void Unbind()
		{
            binder.Unbind(new string[] { "RelativePath", "ImageUrl", "AlternateText", "Enabled", "Visible" });	
		}
		
		//TODO: refactor common button logic
		private void AssignJScriptCommand()
		{
			if(configuration.JScriptCommandName != null)
			{
				this.Attributes.Add("onclick", configuration.JScriptCommandName + "('" + configuration.CommandArgumentGenerator.GenerateCommandArguments(configuration, ExecutionContext.GetCurrent(ClientID)) + "')");
			}
		}




	}
}
